#ifndef _MAT44_HPP
#define _MAT44_HPP

#include <stdio.h>
#include "vec.hpp"

#define M44(m, r, c) m[(c)*4 + (r)]

namespace Tools
{

/* a= b */
void mat44_copy(float *a, const float *b);
/* a= 0 */
void mat44_zero(float *a);

/* a= Id */
void mat44_identity(float *a);

/* a= Id[3x3] */
void mat44_identity33(float *a);

/* a= b * c */
void mat44_mul(float *a, const float *b, const float *c);

/* a= k * b */
void mat44_const_mul(float *a, float k, const float *b);

/* a= a * b */
void mat44_compose(float *a, const float *b);

/* v= a * u */
void mat44_mul_vec(float *v, const float *a, const float *u);

/* u = a * u */
void mat44_compose_vec(const float *a, float *u);

/* u = a * u 
    pour u representant une direction u[3]= 0
 */
void mat44_compose_dir(const float *a, float *u);

/* a= u * u^T */
void mat44_vecT(float *a, const float *v);

void mat44_vec3T(float *a, const float *v);

/* a= b - c */
void mat44_sub(float *a, const float *b, const float *c);

/* a= b + c */
void mat44_add(float *a, const float *b, const float *c);

/* a= inverse(b) 

    adapted from mesa/GLU implementation
 */
int mat44_inverse(float *inverse, const float *src);

void mat44_print(const float *a);

/* coordinate transformation matrix */

/* gl/rt scale */
void mat44_scale(float *a, float x, float y, float z);


/* gl/rt translate */
void mat44_translate(float *a, float x, float y, float z);

/* gl/rt rotate 
    cf. openGL 2 spec
 */
void mat44_rotate(float *a, float angle, float x, float y, float z);

/* adapted from mesa/GLU implementation
 */
void mat44_lookat(float *a, 
    const float *eye, const float *center, const float *up);


void mat44_frustum(float *a, 
    float left, float right, 
    float bottom, float top, 
    float near, float far);

/* adapted from 
 */
void mat44_perspective(float *a, 
    float fovy, float aspect, 
    float near, float far);

}
#endif


